package logger

import (
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"gopkg.in/natefinch/lumberjack.v2"
)

var logger *zap.Logger
var config zap.Config

// env: "dev"|"prod"
// level: "debug"|"info"|...
// logPath: log file path
func InitLogger(env string, level string, logPath string) {
	switch env {
	case "dev":
		initConsoleLogger(level)
	case "prod":
		if logPath == "" {
			logPath = "/tmp/fsd.log"
		}
		initFileLogger(level, logPath)
	default:
		DefaultLogger()
		Warn("init logger error", zap.String("env", env))
	}
}

func DefaultLogger() {
	initConsoleLogger("debug")
}

func initConsoleLogger(level string) {
	var err error
	config = zap.NewDevelopmentConfig()
	config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder

	config.Level = zap.NewAtomicLevelAt(parseLevel(level))

	logger, err = config.Build(zap.AddCallerSkip(1))
	if err != nil {
		Panic(err.Error())
	}
}

func initFileLogger(level string, logPath string) {
	w := zapcore.AddSync(&lumberjack.Logger{
		Filename:   logPath,
		MaxSize:    20,
		MaxBackups: 5,
		MaxAge:     28,
		Compress:   true,
	})
	encoderConfig := zap.NewProductionEncoderConfig()
	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder

	core := zapcore.NewCore(
		zapcore.NewJSONEncoder(encoderConfig),
		w,
		parseLevel(level),
	)
	logger = zap.New(core, zap.AddCallerSkip(1))
}

func parseLevel(level string) (l zapcore.Level) {
	l.Set(level)
	return
}

// wrap
func Debug(msg string, fields ...zap.Field) {
	logger.Debug(msg, fields...)
}

func Info(msg string, fields ...zap.Field) {
	logger.Info(msg, fields...)
}

func Warn(msg string, fields ...zap.Field) {
	logger.Warn(msg, fields...)
}

func Error(msg string, fields ...zap.Field) {
	logger.Error(msg, fields...)
}

func DPanic(msg string, fields ...zap.Field) {
	logger.DPanic(msg, fields...)
}

func Panic(msg string, fields ...zap.Field) {
	logger.Panic(msg, fields...)
}
